package cc.rengu.igas.channel.cups.core.service.trans;

import cc.rengu.igas.channel.cups.common.constant.CupsConfigConstant;
import cc.rengu.igas.channel.cups.common.constant.CupsParamConstant;
import cc.rengu.igas.channel.cups.common.constant.CupsTreeNodeConstant;
import cc.rengu.igas.channel.cups.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.cups.core.model.ChnlBizResponse;
import cc.rengu.igas.channel.cups.core.model.CupsFieldRspBean;
import cc.rengu.igas.channel.cups.core.service.base.BaseManageService;
import cc.rengu.igas.channel.cups.facade.request.CupsResetKeyRequest;
import cc.rengu.igas.channel.cups.facade.response.CupsResetKeyResponse;
import cc.rengu.igas.share.facade.bean.CupsField;
import cc.rengu.igas.share.facade.bean.CupsFieldBean;
import cc.rengu.jradp.schedule.ScheduleImpl;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.DstChannelInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.BeanUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.cache.UnifiedCache;

/**
 * 入网机构发起重置cups密钥申请
 *
 * @author Administrator
 */
public class CupsResetKeyService extends BaseManageService {

    /**
     * 对称密钥 3DES算法，国际
     */
    private static final String DES3 = "3DES";
    /**
     * 对称密钥 SM4算法。国密
     */
    private static final String SM4 = "SM4";

    @Override
    protected Object beforeBizProcess() throws Exception {
        CupsResetKeyRequest cupsResetKeyRequest = new CupsResetKeyRequest();
        ConvertUtil.convertOutput(cupsResetKeyRequest);
        return cupsResetKeyRequest;
    }

    @Override
    protected ChnlBizResponse callBizService(Object request) throws Exception {
        CupsResetKeyRequest cupsResetKeyRequest = (CupsResetKeyRequest) request;
        return directCups(cupsResetKeyRequest);
    }

    @Override
    protected void afterBizProcess(ChnlBizResponse response) throws Exception {
        CupsResetKeyResponse cupsResetKeyResponse = (CupsResetKeyResponse) response.getResult();
        ConvertUtil.convertInput(cupsResetKeyResponse);
    }

    /**
     * 入网机构发起重置密钥
     *
     * @param cupsResetKeyRequest 重置密钥请求体
     * @return
     * @throws Exception
     */
    ChnlBizResponse directCups(CupsResetKeyRequest cupsResetKeyRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        int iReturnCode = 0;
        String algorithm = null;
        ChnlBizResponse chnlBizResponse = new ChnlBizResponse();
        CupsResetKeyResponse cupsResetKeyResponse = new CupsResetKeyResponse();
        SysParamService sysParamService = new SysParamServiceImpl();
        String instId = cupsResetKeyRequest.getHeader().getInstId();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_FWD_INS_CODE);
        if (null == sysParam || StringUtil.isEmptyOrNull(sysParam.getParamValue())) {
            rglog.error("未获取到<{}>机构的发送机构标识", instId);
            throw new BizException(OltpRpcdEnum.PARAM_IS_EMPTY_OR_NULL.getRespCode(), OltpRpcdEnum.PARAM_IS_EMPTY_OR_NULL.getRespDesc());
        }
        String fwdInstCode = sysParam.getParamValue();
        String traceNo = cupsResetKeyRequest.getHeader().getTraceNo();
        String transDateTime = cupsResetKeyRequest.getHeader().getTransDate().substring(4, 8) +
                cupsResetKeyRequest.getHeader().getTransTime();
        String cupsSsn = cupsResetKeyRequest.getHeader().getTransTime();
        DstChannelInfo dstChannelInfo = (DstChannelInfo) xmlTreeUtil.getXmlTreeObjectValue(CupsTreeNodeConstant.DST_CHANNEL_INFO, DstChannelInfo.class);
        sysParam = sysParamService.getSysParamInfo(instId,
                CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_ALG_TYPE);
        if (null != sysParam) {
            algorithm = sysParam.getParamValue();
        }
        CupsField cupsField = new CupsField();
        BeanUtil.beanCopy(cupsResetKeyRequest, cupsField);
        cupsField.setMsgType("0820");
        cupsField.setTransDateTime(transDateTime);
        cupsField.setCupsTraceNo(cupsSsn);
        cupsField.setFwdInstCode(fwdInstCode);
        if (DES3.equals(algorithm)) {
            cupsField.setSecCtrlInfo(cupsResetKeyRequest.getKeyType() + "600000000000000");
        } else if (SM4.equals(algorithm)) {
            cupsField.setSecCtrlInfo(cupsResetKeyRequest.getKeyType() + "400000000000000");
        }
        cupsField.setManageNetCode("101");
        CupsFieldBean cupsFieldBean = new CupsFieldBean();
        cupsFieldBean.setCupsField(cupsField);
        ConvertUtil.convertInput(cupsFieldBean);

        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, cupsResetKeyRequest.getHeader().getTxnNum());
        iReturnCode = schedule.callService(dstChannelInfo.getDstServiceName(), 0);
        String tunlSsn = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.CHANNEL_SEQ_NUM);
        UnifiedCache.remove(CupsParamConstant.CACHE_CUPS_SN, tunlSsn);
        if (ScheduleImpl.SERVICE_TIMEOUT == iReturnCode) {
            rglog.error("调用银联cups服务<{}>超时，iReturnCode:<{}>", dstChannelInfo.getDstServiceName(), iReturnCode);
            cupsResetKeyResponse.setRespCode(OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode());
            cupsResetKeyResponse.setRespDesc(OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespDesc());
            chnlBizResponse.setResult(cupsResetKeyResponse);
            return chnlBizResponse;
        } else if (0 != iReturnCode) {
            rglog.error("调用银联cups服务<{}>失败，iReturnCode:<{}>", dstChannelInfo.getDstServiceName(), iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        CupsFieldRspBean cupsFieldRspBean = new CupsFieldRspBean();
        ConvertUtil.convertOutput(cupsFieldRspBean);
        CupsField cupsFieldRsp = cupsFieldRspBean.getCupsFieldRsp();
        BeanUtil.beanCopy(cupsFieldRsp, cupsResetKeyResponse);
        cupsResetKeyResponse.setRespCode(cupsFieldRsp.getRespCode());

        if (CupsParamConstant.SUCCESS_CODE.equals(cupsResetKeyResponse.getRespCode())) {
            cupsResetKeyResponse.setRespCode(OltpRpcdEnum.TRANS_SUCCESS.getRespCode());
            cupsResetKeyResponse.setRespDesc(OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
        }
        chnlBizResponse.setResult(cupsResetKeyResponse);
        return chnlBizResponse;
    }

}
